
Function.prototype.myCall = function(thisArg = global, ...args) {
  
  // 使用隐式指定 this 的方法将 需要执行的函数 在 thisArg 上执行
  const key = Symbol();
  thisArg[key] = this; // this 为调用 call 的函数
  const result = thisArg[key](...args); // 隐式调用

  delete thisArg[key];
  return result;

}

Function.prototype.myApply = function(thisArg = global, args = []) {
  const key = Symbol();
  thisArg[key] = this;
  const result = thisArg[key](...args);
  delete thisArg[key];
  return result;
}

Function.prototype.myBind = function(thisArg, ...args) {
  const  context = this;
  const newFun = function(...restArgs) {
    if(this instanceof newFun) { // 判断是不是 new 调用的
      return new context(...args, ...restArgs);
    }
    // call()
    const key = Symbol();
    thisArg[key] = context;
    const result = thisArg[key](...args, ...restArgs);
    delete thisArg[key];
    return result;
    
  }

  return newFun;
}

function logName(name, age) {
  this.name = name;
  this.age = age;
  
}
let person = {
  name: 'daxia',
  age: 18,
}

// logName.myCall(person, 'daxia', 34);
// console.log(person)

const personLogName = logName.myBind(person, 'daxia');
personLogName(23)
console.log(person);

console.log(new personLogName(22))
